package com.wwj.server.control.session;

import com.google.gson.GsonBuilder;
import com.wwj.server.model.Message;
import com.wwj.server.model.NetBaseMsg;
import com.wwj.server.session.Session;

import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 会话管理者
 *
 * @author -琴兽-
 */
public class SessionManager {

    /**
     * 娃娃机在线会话
     */
    private static final ConcurrentHashMap<String, Session> onlineWaWaMachineSessions = new ConcurrentHashMap<>();
    /**
     * GameServer在线会话
     */
    private static final ConcurrentHashMap<String, Session> onlineGameServerSessions = new ConcurrentHashMap<>();
    /**
     * NotifyServer在线会话
     */
    private static final ConcurrentHashMap<String, Session> onlineNotifyServerSessions = new ConcurrentHashMap<>();

    public static final String PREFIX_SESSION_KEY_WA_WA_MACHINE = "WaWaMachine@";
    public static final String PREFIX_SESSION_KEY_GAME_SERVER = "GameServer@";
    public static final String PREFIX_SESSION_KEY_NOTIFY_SERVER = "NotifyServer@";


    /**
     * 加入
     *
     * @param sessionKey
     * @param session
     * @return
     */
    public static boolean putSession(String sessionKey, Session session) {
        if (sessionKey.startsWith(PREFIX_SESSION_KEY_GAME_SERVER)) {
            if (!onlineGameServerSessions.containsKey(sessionKey)) {
                return onlineGameServerSessions.putIfAbsent(sessionKey, session) == null;
            } else {
                Session oldSession = onlineGameServerSessions.get(sessionKey);
                session.setAttachment(oldSession.getAttachment());
                return onlineGameServerSessions.replace(sessionKey, oldSession, session);
            }
        } else if (sessionKey.startsWith(PREFIX_SESSION_KEY_NOTIFY_SERVER)) {
            if (!onlineNotifyServerSessions.containsKey(sessionKey)) {
                return onlineNotifyServerSessions.putIfAbsent(sessionKey, session) == null;
            } else {
                Session oldSession = onlineNotifyServerSessions.get(sessionKey);
                session.setAttachment(oldSession.getAttachment());
                return onlineNotifyServerSessions.replace(sessionKey, oldSession, session);
            }
        } else if (sessionKey.startsWith(PREFIX_SESSION_KEY_WA_WA_MACHINE)) {
            if (!onlineWaWaMachineSessions.containsKey(sessionKey)) {
                return onlineWaWaMachineSessions.putIfAbsent(sessionKey, session) == null;
            } else {
                Session oldSession = onlineWaWaMachineSessions.get(sessionKey);
                session.setAttachment(oldSession.getAttachment());
                return onlineWaWaMachineSessions.replace(sessionKey, oldSession, session);
            }
        }
        return false;
    }

    /**
     * 移除
     *
     * @param sessionKey
     */
    public static Session removeSession(String sessionKey) {
        if (sessionKey.startsWith(PREFIX_SESSION_KEY_GAME_SERVER)) {
            return onlineGameServerSessions.remove(sessionKey);
        } else if (sessionKey.startsWith(PREFIX_SESSION_KEY_NOTIFY_SERVER)) {
            return onlineNotifyServerSessions.remove(sessionKey);
        } else if (sessionKey.startsWith(PREFIX_SESSION_KEY_WA_WA_MACHINE)) {
            return onlineWaWaMachineSessions.remove(sessionKey);
        }
        return null;
    }

//    /**
//     * 发送消息[自定义协议]
//     *
//     * @param <T>
//     * @param sessionKey
//     * @param message
//     */
//    public static <T extends Serializer> void sendMessage(String sessionKey, T message) {
//        Session session = onlineSessions.get(sessionKey);
//        if (session != null && session.isConnected()) {
//            Message msg = new Message(message.getBytes());
//            session.write(msg);
//        }
//    }

//    /**
//     * 发送消息[protoBuf协议]
//     *
//     * @param <T>
//     * @param sessionKey
//     * @param message
//     */
//    public static <T extends GeneratedMessage> void sendMessage(String sessionKey, T message) {
//        Session session = onlineSessions.get(sessionKey);
//        if (session != null && session.isConnected()) {
//            Message msg = new Message(message.toByteArray());
//            session.write(msg);
//        }
//    }

    public static <T extends NetBaseMsg> void sendMessage(String sessionKey, T message) {
        Session session = null;

        if (sessionKey.startsWith(PREFIX_SESSION_KEY_GAME_SERVER)) {
            session = onlineGameServerSessions.get(sessionKey);
        } else if (sessionKey.startsWith(PREFIX_SESSION_KEY_NOTIFY_SERVER)) {
            session = onlineNotifyServerSessions.get(sessionKey);
        } else if (sessionKey.startsWith(PREFIX_SESSION_KEY_WA_WA_MACHINE)) {
            session = onlineWaWaMachineSessions.get(sessionKey);
        }

        if (session != null && session.isConnected()) {
            Message msg = new Message(new GsonBuilder()
                    .disableHtmlEscaping()
                    .serializeNulls().create().toJson(message).getBytes());
            session.write(msg);
        }
    }

    public static <T extends NetBaseMsg> void sendMessageToAll(String prefix, T message) {
        ConcurrentHashMap<String, Session> temp = null;
        if (prefix.equals(PREFIX_SESSION_KEY_GAME_SERVER)) {
            temp = onlineGameServerSessions;
        } else if (prefix.equals(PREFIX_SESSION_KEY_NOTIFY_SERVER)) {
            temp = onlineNotifyServerSessions;
        } else if (prefix.equals(PREFIX_SESSION_KEY_WA_WA_MACHINE)) {
            temp = onlineWaWaMachineSessions;
        }

        if (temp != null && temp.size() > 0) {
            Iterator<String> it = temp.keySet().iterator();
            String sessionKey = "";
            Session session = null;
            Message msg = null;
            while (it.hasNext()) {
                sessionKey = it.next();
                session = temp.get(sessionKey);
                if (null != session && session.isConnected()) {
                    msg = new Message(new GsonBuilder()
                            .disableHtmlEscaping()
                            .serializeNulls().create().toJson(message).getBytes());
                    session.write(msg);
                }
            }

        }
    }

    /**
     * 是否在线
     *
     * @param sessionKey
     * @return
     */
    public static boolean isOnline(String sessionKey) {
        if (sessionKey.startsWith(PREFIX_SESSION_KEY_GAME_SERVER)) {
            return onlineGameServerSessions.containsKey(sessionKey);
        } else if (sessionKey.startsWith(PREFIX_SESSION_KEY_NOTIFY_SERVER)) {
            return onlineNotifyServerSessions.containsKey(sessionKey);
        } else if (sessionKey.startsWith(PREFIX_SESSION_KEY_WA_WA_MACHINE)) {
            return onlineWaWaMachineSessions.containsKey(sessionKey);
        }
        return false;
    }

//    /**
//     * 获取所有在线session
//     *
//     * @return
//     */
//    public static Set<String> getOnline() {
//        return Collections.unmodifiableSet(onlineSessions.keySet());
//    }
}
